package cn.osworks.aos.system.modules.service.toolkit;

import java.io.File;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

import cn.core.autobuilder.dao.mapper.Builder_tableMapper;
import cn.core.autobuilder.dao.po.Builder_tablePO;
import cn.core.autobuilder.service.Builer_codeService;
import cn.osworks.aos.builder.DaoBuilder;
import cn.osworks.aos.builder.VCBuilder;
import cn.osworks.aos.builder.db.DbTableInfo;
import cn.osworks.aos.builder.metainfo.DBMetaInfoUtils;
import cn.osworks.aos.builder.metainfo.vo.ColumnVO;
import cn.osworks.aos.builder.metainfo.vo.TableVO;
import cn.osworks.aos.core.asset.AOSCons;
import cn.osworks.aos.core.asset.AOSListUtils;
import cn.osworks.aos.core.asset.AOSUtils;
import cn.osworks.aos.core.asset.WebCxt;
import cn.osworks.aos.core.dao.SqlDao;
import cn.osworks.aos.core.typewrap.Dto;
import cn.osworks.aos.core.typewrap.Dtos;
import cn.osworks.aos.system.dao.po.Aos_sys_modulePO;
import cn.osworks.aos.system.modules.service.resource.ModuleService;
import cn.osworks.aos.web.tag.core.model.TreeNode;

/**
 * 代码生成器服务
 * 
 * @author AHei
 */
@Service
public class CoderService {

	@Autowired
	private Builer_codeService builer_codeservice;
	@Autowired
	private Builder_tableMapper builder_tablemapper;
	@Autowired
	private SqlDao sqlDao;
	@Autowired
	private ModuleService moduleService;

	/**
	 * 列出表字段
	 * 
	 * @return
	 */
	public List<ColumnVO> listColumns(Dto pDto) {

		return null;
	}

	/**
	 * 列出数据表(树状结构)
	 * 
	 * @return
	 */
	public List<TreeNode> listTablesAsTree(Dto pDto) {
		List<TableVO> tableVOs = Lists.newArrayList();
		List<TreeNode> tableList = Lists.newArrayList();
		for (TableVO tableVO : tableVOs) {
			TreeNode treeNode = new TreeNode();
			treeNode.setId("_id" + tableVO.getName());
			treeNode.setA(tableVO.getName());
			String text = tableVO.getName();
			String comment = tableVO.getComment();
			treeNode.setQtip(comment);
			if (AOSUtils.isNotEmpty(comment)) {
				if (comment.length() >= 10) {
					comment = StringUtils.substring(comment, 0, 9);
					comment = comment + "...";
				}
				text = text + "(" + comment + ")";
			}
			treeNode.setText(text);
			treeNode.setLeaf(true);
			treeNode.setIcon("table.png");
			tableList.add(treeNode);
		}
		return tableList;
	}

	/**
	 * 列出数据表
	 * 
	 * @return
	 * @throws SQLException
	 */
	public List<TableVO> listTables(Dto inDto) throws SQLException {
		List<TableVO> tableVOs = DBMetaInfoUtils.listTableVOs(DBMetaInfoUtils.getDatabaseMetaData(),
				inDto.getString("name_"));
		for (TableVO tableVO : tableVOs) {
			if (AOSUtils.isEmpty(tableVO.getComment()) || StringUtils.startsWithIgnoreCase(tableVO.getComment(), "InnoDB")) {
				tableVO.setComment(tableVO.getName());
			}
		}
		return tableVOs;
	}

	/**
	 * 查询数据表注释
	 * 
	 * @param tableNameString
	 * @return
	 */
	public String selectTableComment(String tableNameString) {
		String commnet = "";
		return commnet;
	}

	/**
	 * 生成项目结构树
	 * 
	 * @param queryDto
	 * @return
	 */
	public List<TreeNode> listProjectView(Dto queryDto) {
		List<TreeNode> fileList = Lists.newArrayList();
		String path = queryDto.getString("path");
		if (StringUtils.equalsIgnoreCase("aosroot_", path)) {
			// 根节点
			String coder_project_rootpath_ = WebCxt.getCfgOfDB("coder_project_rootpath_");
			if (StringUtils.equals(coder_project_rootpath_, "0")) {
				path = System.getProperty("user.dir");
			} else {
				path = coder_project_rootpath_;
			}
		}
		String os = System.getProperty("os.name");  
		File file = new File(path);
		if (file.exists()) {
			File[] subFiles = file.listFiles();
			for (File subFile : subFiles) {
				TreeNode treeNode = new TreeNode();
				String subPath = subFile.getAbsolutePath();
				treeNode.setId(subPath);
				String filename = subFile.getName();
				if (StringUtils.startsWith(filename, "."))
					continue;
				if (filename.equalsIgnoreCase("classes"))
					continue;
				if (filename.equalsIgnoreCase("icon"))
					continue;
				if (filename.equalsIgnoreCase("image"))
					continue;
				if (filename.equalsIgnoreCase("data") || filename.equalsIgnoreCase("report")
						|| filename.equalsIgnoreCase("tld") || filename.equalsIgnoreCase("lib")
						|| filename.equalsIgnoreCase("db"))
					continue;
				treeNode.setText(filename);
				if (subFile.isDirectory()) {
					// 目录
					treeNode.setA("1");
					
					if (StringUtils.contains(subPath, "java\\")||StringUtils.contains(subPath, "java/")) {
						
						if(StringUtils.contains(subPath, "dao")){
							treeNode.setB("1");
					     }else if(StringUtils.contains(subPath, "service")){
					    	treeNode.setB("2");
					     }else if(StringUtils.contains(subPath, "controller")){
						    	treeNode.setB("3");
						 }else {
							 treeNode.setB("5");
						 }
						// java package
						treeNode.setIcon("icon34.gif");
						// 目录类型：java源文件包
						
						String pkgpath = StringUtils.substringAfter(subPath, "java\\");
						pkgpath = AOSUtils.isEmpty(pkgpath)?StringUtils.substringAfter(subPath, "java/"):pkgpath;
						if(os.toLowerCase().startsWith("win")){
							pkgpath = pkgpath.replace("\\", ".");
						}else{
							pkgpath = pkgpath.replace("/", ".");
						}
						treeNode.setC(pkgpath);
						
					} else if (StringUtils.contains(subPath, "webapp\\") || StringUtils.contains(subPath, "webapp/") ) {
						if(StringUtils.contains(subPath, "jsp")){
							 treeNode.setB("4");
						 }
						treeNode.setIcon("icon42.gif");
					} else {
						treeNode.setIcon("icon35.gif");
					}
					if (filename.equalsIgnoreCase("webapp")) {
						treeNode.setIcon("icon42.gif");
					}
					treeNode.setLeaf(false);
				} else {
					// 文件
					treeNode.setA("2");
					treeNode.setLeaf(true);
					if (StringUtils.endsWith(filename, "java")) {
						treeNode.setIcon("icon36.gif");
					} else if (StringUtils.endsWith(filename, "xml")) {
						treeNode.setIcon("icon39.gif");
					} else if (StringUtils.endsWith(filename, "js")) {
						treeNode.setIcon("icon37.gif");
					} else if (StringUtils.endsWith(filename, "jsp")) {
						treeNode.setIcon("icon26.gif");
					} else {
						treeNode.setIcon("icon38.gif");
					}
				}
				if (StringUtils.equalsIgnoreCase("webapp", treeNode.getText())
						|| StringUtils.equalsIgnoreCase("WEB-INF", treeNode.getText())
						|| StringUtils.equalsIgnoreCase("src", treeNode.getText())) {
					treeNode.setExpanded(true);
				}
				fileList.add(treeNode);
			}
		}
		// 重排序，树枝节点排在前面
		String jqlText = "SELECT * FROM :AOSList ORDER BY toNumber(a) ASC";
		fileList = AOSListUtils.select(fileList, TreeNode.class, jqlText, null);
		return fileList;
	}

	/**
	 * 生成Dao代码
	 * @throws SQLException 
	 */
	public Dto buildDaoCode(Dto inDto) throws SQLException {
		Dto outDto = Dtos.newDto();
		inDto.put("package", inDto.getString("package_"));
		inDto.put("author", inDto.getString("author"));
		String[] tables = inDto.getRows();
	    DatabaseMetaData databaseMetaData = DBMetaInfoUtils.getDatabaseMetaData();
		for (String tableName : tables) {
			inDto.put("table_name_", tableName);
			inDto.put("db_name_", inDto.getString("db_name_").split(",")[0]);
			inDto.put("table_name", tableName);
			inDto.put("daopackage_", inDto.getString("package_"));
			//builer_codeservice.importtableinfo(inDto);
			DbTableInfo dbtableinfo = new DbTableInfo();
			ArrayList<Dto> tableList = dbtableinfo.getTabelInfoByBuilder_code(DBMetaInfoUtils.newConnection(), inDto);
			if(AOSUtils.isEmpty(tableList)){
				//("生成出错，请检查配置表是否存在于表builder_code，自动生成终止。");
				outDto.setAppCode(AOSCons.ERROR);
				outDto.setAppMsg("生成出错，请先导入"+tableName+"表结构到系统，自动生成终止。");
				return outDto;
			}
			
			TableVO tableVO = DBMetaInfoUtils.getTableVO(databaseMetaData, tableName);
			if (AOSUtils.isEmpty(tableVO)) {
				outDto.setAppCode(AOSCons.ERROR);
				outDto.setAppMsg("表[" + tableName + "]不存在。");
				//throw new AOSException("表[" + tableName + "]不存在。");
			}
			inDto.put("tableVO", tableVO);
			inDto.put("tablelist", tableList);
			List<ColumnVO> columnVOs = DBMetaInfoUtils.listColumnVOs(databaseMetaData, tableName);
			//仅生成XMLMapper时需要
			List<ColumnVO> pkeyColumnVOs = DBMetaInfoUtils.getPKColumnVOs(columnVOs);
			inDto.put("columnVOs", columnVOs);
			inDto.put("pkeyColumnVOs", pkeyColumnVOs);
			DaoBuilder.buildPO(inDto);
			DaoBuilder.buildJavaMapper(inDto);
			DaoBuilder.buildXmlMapper(inDto);
			Builder_tablePO builder_tablepo =(Builder_tablePO)sqlDao.selectOne("Builder_table.queryBuilder_table", inDto);
			builder_tablepo.setDaopackage_( inDto.getString("daopackage_") );
			builder_tablemapper.updateByKey(builder_tablepo);
		}
		outDto.setAppCode(AOSCons.SUCCESS);
		outDto.setAppMsg("代码生成成功,请进入下一步生成Service文件，请刷新工程后重启服务器。");
		return outDto;
	}
	
	/**
	 * 生成Service代码
	 * @throws SQLException 
	 */
	public Dto buildServiceCode(Dto inDto) throws SQLException {
		inDto.put("package", inDto.getString("package_"));
		inDto.put("author", inDto.getString("author"));
		Dto outDto = Dtos.newDto();
		String codetype = inDto.getString("codetype");
		String[] tables = inDto.getRows();
		for (int i=0;i<tables.length;i++) {
			String tableName = tables[i];
			if(AOSUtils.isEmpty(tableName)){
				continue;
			}
			inDto.put("table_name_", tableName);
			inDto.put("db_name_", inDto.getString("db_name_").split(",")[i]);
			inDto.put("package_", inDto.getString("package_"));  //生成的路径
		    String daopackage_ = inDto.getString("daopackage_");
			inDto.put("controllername", inDto.getString("controlname"));
			// dto.put("author", "hepeng");  
			inDto.put("tables", tableName);
			DbTableInfo dbtableinfo = new DbTableInfo();
			inDto.put("table_name", tableName);
			String name = StringUtils.lowerCase(tableName);
			inDto.put("classname",name);    
			inDto.put("upname", StringUtils.capitalize(name)); 
			ArrayList<Dto> tableList = dbtableinfo.getTabelInfoByBuilder_code(DBMetaInfoUtils.newConnection(), inDto);
			if(AOSUtils.isEmpty(tableList)){
				//("生成出错，请检查配置表是否存在于表builder_code，自动生成终止。");
				outDto.setAppCode(AOSCons.ERROR);
				outDto.setAppMsg("生成出错，请检查配置表"+tableName+"是否存在于表builder_code，自动生成终止。");
				return outDto;
			}
			Dto table_head = dbtableinfo.getTabelInfoByBuilder_Table(DBMetaInfoUtils.newConnection(), inDto);
			inDto.put("tableList", tableList);
			inDto.put("table_head", table_head);
			if(codetype.equals("Service")){
				String []daotest = daopackage_.split(",");
				if(daotest.length!=tables.length){
					outDto.setAppCode(AOSCons.ERROR);
					outDto.setAppMsg("代码生成错误，请先生成Dao文件");
					return outDto;
				}
				inDto.put("daopackage", inDto.getString("daopackage_").split(",")[i]);
				VCBuilder.bulidService(inDto);
				Builder_tablePO builder_tablePO= new Builder_tablePO();
				builder_tablePO.setId_(inDto.getString("id_").split(",")[i]);
				builder_tablePO.setServicepackage_(inDto.getString("package_"));
				builder_tablemapper.updateByKey(builder_tablePO);
				outDto.setAppMsg("代码生成成功，请进入下一步生成Controller文件");
			}else if(codetype.equals("Controller")){	
				String servicepackage_=inDto.getString("servicepackage_");
				String[] serviceTest=servicepackage_.split(",");
				if(serviceTest.length!=tables.length){
					outDto.setAppCode(AOSCons.ERROR);
					outDto.setAppMsg("代码生成错误，请先生成Service文件");
					return outDto;
				}
				inDto.put("daopackage", inDto.getString("daopackage_").split(",")[i]);
				String []daotest = daopackage_.split(",");
				if(daotest.length!=tables.length){
					outDto.setAppCode(AOSCons.ERROR);
					outDto.setAppMsg("代码生成错误，请先生成Dao文件");
					return outDto;
				}
				String jsp_path=inDto.getString("jsp_path_");
				inDto.put("jsp_path", jsp_path);
				inDto.put("servicepackage", inDto.getString("servicepackage_").split(",")[i]);
				Builder_tablePO builder_tablePO= new Builder_tablePO();
				builder_tablePO.setId_(inDto.getString("id_").split(",")[i]);
				builder_tablePO.setControllername_(inDto.getString("controlname"));
				builder_tablePO.setControllerpaceage_(inDto.getString("package_"));
				builder_tablePO.setJsp_path_(inDto.getString("jsp_path_"));
				builder_tablemapper.updateByKey(builder_tablePO);
				VCBuilder.buildController(inDto);
				
				Dto menuDto= Dtos.newDto();
				menuDto.put("parent_id_", "94c5be429ebb4a3a8b62c4a2f3e6a511");
				menuDto.put("is_auto_expand_", "0");
				menuDto.put("status_", "1");
				String url=inDto.getString("controlname")+"/"+inDto.getString("classname")+"/init.jhtml";
				menuDto.put("url_", url);
				menuDto.put("name_", table_head.get("table_des_"));
				menuDto.put("sort_no_", "1");
				menuDto.put("id_", "94c5be429ebb4a3a8b62c4a2f3e6a511");
				List<Aos_sys_modulePO> aos_sys_modulePOs = sqlDao.list("Resource.listAos_sys_modulePOs", menuDto);
				if(AOSUtils.isEmpty(aos_sys_modulePOs)){
					menuDto.remove("id_");
					moduleService.saveModule(menuDto);
				}
				outDto.setAppMsg("代码生成成功，请进入下一步生成JSP文件");
			}else if(codetype.equals("JSP")){
				String servicepackage_ = inDto.getString("servicepackage_");
				String []daotest = daopackage_.split(",");
				if(daotest.length!=tables.length){
					outDto.setAppCode(AOSCons.ERROR);
					outDto.setAppMsg("代码生成错误，请先生成Dao文件");
					return outDto;
				}
				String []servicetest = servicepackage_.split(",");
				if(servicetest.length!=tables.length){
					outDto.setAppCode(AOSCons.ERROR);
					outDto.setAppMsg("代码生成错误，请先生成Service文件");
					return outDto;
				}
				String outJSPPath = inDto.getString("outPath");
				inDto.put("outJSPPath", outJSPPath);
				inDto.put("controllername", inDto.getString("controllername_").split(",")[i]);
				Builder_tablePO builder_tablePO= new Builder_tablePO();
			 
				if( outJSPPath.indexOf("jsp")>-1 &&  outJSPPath.length()>outJSPPath.indexOf("jsp")+4  && AOSUtils.isEmpty(inDto.get("jsp_path_")) ){
					String jsp_path_=outJSPPath.substring(outJSPPath.indexOf("jsp")+4, outJSPPath.length());
					builder_tablePO.setJsp_path_(jsp_path_);
				}
				builder_tablePO.setId_(inDto.getString("id_").split(",")[i]);
				builder_tablemapper.updateByKey(builder_tablePO);
				VCBuilder.bulidJSP(inDto);
				outDto.setAppMsg("代码生成成功,请刷新工程后重启服务器。");
			}else if(codetype.equals("SqlMapper")){
				String []daotest = daopackage_.split(",");
				if(daotest.length!=tables.length){
					outDto.setAppCode(AOSCons.ERROR);
					outDto.setAppMsg("代码生成错误，请先生成Dao文件");
					return outDto;
				}
				inDto.put("daopackage", inDto.getString("daopackage_").split(",")[i]);
				VCBuilder.bulidSqlMapper(inDto);
				Builder_tablePO builder_tablePO= new Builder_tablePO();
				builder_tablePO.setId_(inDto.getString("id_").split(",")[i]);
				builder_tablePO.setSqlmapper_(inDto.getString("package_"));
				builder_tablemapper.updateByKey(builder_tablePO);
				outDto.setAppMsg("代码生成成功,SqlMapper已生成成功。 ");
			}
		}
		outDto.setAppCode(AOSCons.SUCCESS);
		return outDto;
	}

}
